const path = require('path')
const MiniCssPlugin = require('mini-css-extract-plugin')
const UglifyJsPlugin = require("uglifyjs-webpack-plugin")
const OptimizeCSSAssetsPlugin = require("optimize-css-assets-webpack-plugin")
const HtmlWebpackPlugin = require('html-webpack-plugin')
const CleanWebpackPlugin = require('clean-webpack-plugin')
const internalIp = require('internal-ip')
// const webpack = require('webpack')
const config = require('./build/config')
const dev = Boolean(process.env.WEBPACK_SERVE)
const rules = config.rules({
    dev
})

/**
 * ==================
 * PLUGINS
 * ==================
 */

const plugins = [
    new MiniCssPlugin({
        filename: dev ? '[name].css' : 'css/[name].[contenthash:8].css',
        chunkFilename: dev ? '[name].css' : 'css/[name].[contenthash:8].css'
    }),
    new HtmlWebpackPlugin({
        filename: './view/index.html',
        template: './view/index.html',
        chunks: ['main']
    })
]

/**
 * ==================
 * MAIN CONFIG
 * ==================
 */
const assets = path.resolve(__dirname, './')
let clientConfig = {
    mode: dev ? 'development' : 'production',
    context: assets,
    entry: {},
    output: {
        path: path.join(assets, 'dist'),
        filename: dev ? '[name].js' : 'scripts/bundle-[chunkhash:8].js',
        // 由于使用了webpack-serve来启动服务，该服务的服务器起始位置默认是项目根目录，同时使用了html-webpack-plugin插件，此属性才会起作用
        // 如果使用的是webpack-dev-server来启动服务，则可以指定服务器的起始目录，如：publicPath: dev ? '/assets/' : '../'
        publicPath: dev ? '../' : '../'
    },
    module: {
        rules: [
            rules.babel,
            rules.css,
            rules.image
        ]
    },
    resolve: {
        extensions: ['*', '.js', '.json', '.vue', '.tsx', '.ts'],
        alias: {
            // static: path.resolve(assets, '../static/')
        }
    },
    plugins: plugins,
    devtool: dev ? 'source-map' : false,
    performance: {
        hints: false
    },
    // 是否在控制台显示统计信息
    stats: 'normal'
}

const setEntry = (config, obj) => {
    // let hmr = 'webpack-hot-middleware/client?path=/__webpack_hmr'
    for (let key in obj) {
        config.entry[key] = [obj[key]]
        // dev && config.entry[key].unshift(hmr)
    }
}

// 需要编译的入口
let entries = {
    main: './src/script/main.js'
}

setEntry(clientConfig, entries)

/**
 * ==================
 * 开发环境和生产环境配置区分
 * ==================
 */
if (dev) {
    clientConfig.cache = true
    // 此选项配合webpack-dev-server插件使用，
    clientConfig.devServer = {
        port: config.port,
        host: '0.0.0.0.',
        // 设置webpack-dev-server服务器根路径
        publicPath: './dist',
        // 在开发单页应用时非常有用，它依赖于HTML5 history API，如果设置为true，所有的跳转将指向index.html
        historyApiFallback: true,
        noInfo: true,
        // 在编译出错的时候，是否在浏览器页面上显示错误
        overlay: true,
        // 允许热加载
        hot: true
    }
    // 此选项配合webpack-serve插件使用
    clientConfig.serve = {
        host: '0.0.0.0',
        hot: {
            host: {
                client: internalIp.v4.sync(),
                server: '0.0.0.0'
            }
        },
        port: config.port,
        add: (app, middleware, options) => {
            // 模拟后端接口请求
            app.use((ctx, next) => {
                if (ctx.request.path === '/api/types') {
                    ctx.response.type = 'json'
                    ctx.response.body = { data: ['资讯','设计'] }
                }
                next()
            })
        }
    }
} else {
    clientConfig.plugins.unshift(
        // 构建的时候先清空dist目录
        new CleanWebpackPlugin('./dist/*', {
            root: __dirname,
            // 是否显示在控制台
            verbose: true,
            // 是否模拟删除
            dry: false
        }))
    clientConfig.optimization = {
        // 生产用压缩
        minimizer: [
            // js压缩
            new UglifyJsPlugin({
                uglifyOptions: {
                    compress: {
                        // warnings: false,
                        // 删除所有的“console”语句
                        // drop_console: true,
                        // 如果需要去除console.log 保留 console.error或者console.info的话，使用下面这个配置，如果需要去除所有的console函数,则使用上面的drop_console属性
                        pure_funcs: ['console.log']
                    }
                },
                cache: true,
                parallel: true,
                sourceMap: true // set to true if you want JS source maps
            }),
            // css压缩
            new OptimizeCSSAssetsPlugin({})
        ]
    }
}

module.exports = clientConfig